import axios from 'axios'
import type { AxiosInstance } from 'axios'
import { type ServiceRequestConfig, DEAFULT_LOADING, type ServiceRequestInterceptors,RETURN_DATA } from './type'
import { userStore } from "@/store/index";
import { storeToRefs } from 'pinia'

class request {
	instance : AxiosInstance
	interceptors ?: ServiceRequestInterceptors
	showLoading : boolean = DEAFULT_LOADING
	constructor(config : ServiceRequestConfig) {
		this.instance = axios.create(config)
		this.interceptors = config.interceptors
		this.alone()
		this.all()
	}
	alone() {
		// 注册单例请求拦截
		this.instance.interceptors.request.use(
			this.interceptors?.requestInterceptor,
			this.interceptors?.requestInterceptorCatch
		)
		// 注册单例响应拦截
		this.instance.interceptors.response.use(
			this.interceptors?.responseInterceptor,
			this.interceptors?.responseInterceptorCatch
		)
	}
	all() {
		// 注册全局请求拦截
		this.instance.interceptors.request.use(
			(config) => {
				const store = userStore()
				const {token} = storeToRefs(store)
				if(token.value){
					// 请求之前获取token
					config.headers['Authorization'] = `Bearer ${token.value}`
				}
				return config
			},
			(err) => {
				return err
			}
		)
		// 注册全局响应拦截
		this.instance.interceptors.response.use(
			(res) => {
				const {code,message} = res.data
				if(code != 200){
					window.$message.error(message)
				}
				return res
			},
			(err) => {
				return err
			}
		)
	}
	// 网络请求
	request<T = any>(config : ServiceRequestConfig) : Promise<T> {
		return new Promise((resolve, reject) => {
			// 单独请求拦截
			config = config.interceptors?.requestInterceptor
				? config.interceptors.requestInterceptor(config)
				: config
			this.instance
				.request<T, any>(config)
				.then((res) => {
					// 单独响应拦截
					res = config.interceptors?.responseInterceptor
						? config.interceptors.responseInterceptor(res)
						: res
					
					res = config.returnData?res:res.data
					resolve(res)
				})
				.catch((err) => {
					reject(err)
				})
		})
	}
	get<T = any>(config : ServiceRequestConfig) : Promise<T> {
		return this.request({ ...config, method: "GET" })
	}
	post<T = any>(config : ServiceRequestConfig) : Promise<T> {
		return this.request({ ...config, method: "POST" })
	}

	delete<T = any>(config : ServiceRequestConfig) : Promise<T> {
		return this.request({ ...config, method: "DELETE" })
	}
	patch<T = any>(config : ServiceRequestConfig) : Promise<T> {
		return this.request({ ...config, method: "PATCH" })
	}
}
export default request